home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / pine / osdep / tempnam < prev    next >
Text File  |  1996-04-26  |  4KB  |  154 lines

  1. /*
  2.  * This routine is derived from BSD4.3 code,
  3.  * Copyright (c) 1988 Regents of the University of California.
  4.  * All rights reserved.
  5.  */
  6. #if defined(LIBC_SCCS) && !defined(lint)
  7. static char sccsid[] = "@(#)tmpnam.c    4.5 (Berkeley) 6/27/88";
  8. #endif /* LIBC_SCCS and not lint */
  9. /*----------------------------------------------------------------------
  10.       Return a unique file name in a given directory.  This is not quite
  11.       the same as the usual tempnam() function, though it is very similar.
  12.       We want it to use the TMP environment variable only if dir is NULL,
  13.       instead of using TMP regardless if it is set.
  14.  
  15.   Args: dir      -- The directory to create the name in
  16.         prefix   -- Prefix of the name
  17.  
  18.  Result: Malloc'd string equal to new name is returned.  It must be free'd
  19.      by the caller.  Returns the string on success and NULL on failure.
  20.   ----*/
  21. char *
  22. temp_nam(dir, prefix)
  23.     char *dir, *prefix;
  24. {
  25.     struct stat buf;
  26.     char *f, *name;
  27.     char *our_mktemp();
  28.  
  29.     if (!(name = malloc((unsigned int)MAXPATHLEN)))
  30.         return((char *)NULL);
  31.  
  32.     if (!dir && (f = getenv("TMPDIR")) && !stat(f, &buf) &&
  33.                          (buf.st_mode&S_IFMT) == S_IFDIR &&
  34.              !can_access(f, WRITE_ACCESS|EXECUTE_ACCESS)) {
  35.         (void)strcpy(name, f);
  36.         goto done;
  37.     }
  38.  
  39.     if (dir && !stat(dir, &buf) &&
  40.                          (buf.st_mode&S_IFMT) == S_IFDIR &&
  41.                      !can_access(dir, WRITE_ACCESS|EXECUTE_ACCESS)) {
  42.         (void)strcpy(name, dir);
  43.         goto done;
  44.     }
  45.  
  46. #ifndef P_tmpdir
  47. #define    P_tmpdir    "/usr/tmp"
  48. #endif
  49.     if (!stat(P_tmpdir, &buf) &&
  50.                          (buf.st_mode&S_IFMT) == S_IFDIR &&
  51.              !can_access(P_tmpdir, WRITE_ACCESS|EXECUTE_ACCESS)) {
  52.         (void)strcpy(name, P_tmpdir);
  53.         goto done;
  54.     }
  55.  
  56.     if (!stat("/tmp", &buf) &&
  57.                          (buf.st_mode&S_IFMT) == S_IFDIR &&
  58.              !can_access("/tmp", WRITE_ACCESS|EXECUTE_ACCESS)) {
  59.         (void)strcpy(name, "/tmp");
  60.         goto done;
  61.     }
  62.     free((void *)name);
  63.     return((char *)NULL);
  64.  
  65. done:
  66.     if(*(f = &name[strlen(name) - 1]) != '/')
  67.       *++f = '/';
  68.  
  69.     f++;
  70.     if (prefix)
  71.       sstrcpy(&f, prefix);
  72.  
  73.     sstrcpy(&f, "XXXXXX");
  74.     return(our_mktemp(name));
  75. }
  76.  
  77.  
  78. /*
  79.  * This routine is derived from BSD4.3 code,
  80.  * Copyright (c) 1987 Regents of the University of California.
  81.  * All rights reserved.
  82.  *
  83.  * We use this instead of mktemp() since we know of at least one stupid
  84.  * mktemp() (AIX3.2) which breaks things.
  85.  */
  86. #if defined(LIBC_SCCS) && !defined(lint)
  87. static char sccsid[] = "@(#)mktemp.c    5.7 (Berkeley) 6/27/88";
  88. #endif /* LIBC_SCCS and not lint */
  89.  
  90. static
  91. _gettemp(as)
  92.     char    *as;
  93. {
  94.     extern int    errno;
  95.     register char    *start, *trv;
  96.     struct stat    sbuf;
  97.     unsigned    pid;
  98.  
  99.     pid = (unsigned)getpid();
  100.  
  101.     /* extra X's get set to 0's */
  102.     for (trv = as; *trv; ++trv);
  103.     while (*--trv == 'X') {
  104.         *trv = (pid % 10) + '0';
  105.         pid /= 10;
  106.     }
  107.  
  108.     /*
  109.      * check for write permission on target directory; if you have
  110.      * six X's and you can't write the directory, this will run for
  111.      * a *very* long time.
  112.      */
  113.     for (start = ++trv; trv > as && *trv != '/'; --trv);
  114.     if (*trv == '/') {
  115.         *trv = '\0';
  116.         if (stat(as==trv ? "/" : as, &sbuf)
  117.             || !(sbuf.st_mode & S_IFDIR))
  118.             return(0);
  119.         *trv = '/';
  120.     }
  121.     else if (stat(".", &sbuf) == -1)
  122.         return(0);
  123.  
  124.     for (;;) {
  125.         if (stat(as, &sbuf))
  126.             return(errno == ENOENT ? 1 : 0);
  127.  
  128.         /* tricky little algorithm for backward compatibility */
  129.         for (trv = start;;) {
  130.             if (!*trv)
  131.                 return(0);
  132.             if (*trv == 'z')
  133.                 *trv++ = 'a';
  134.             else {
  135.                 if (isdigit((unsigned char)*trv))
  136.                     *trv = 'a';
  137.                 else
  138.                     ++*trv;
  139.                 break;
  140.             }
  141.         }
  142.     }
  143.     /*NOTREACHED*/
  144. }
  145.  
  146. char *
  147. our_mktemp(as)
  148.     char    *as;
  149. {
  150.     return(_gettemp(as) ? as : (char *)NULL);
  151. }
  152.  
  153.  
  154.